/*
 * TaskInstructionDescription.java
 * 
 * last update: 16.01.2010 by Stefan Saru
 * 
 * author:	Alec(panovici@elcom.pub.ro)
 * 
 * Obs:
 */

package engine;

import middle.*;
import java.util.*;

/**
 * The description of a task activation instruction. 
 * It creates the required registers for the actual parameters (whose types are known only at instantiation time).
 */
@SuppressWarnings("serial")
class TaskInstructionDescription extends InstructionDescription{

	/**
	 * Contains the expressionDescriptions for the actual parameters.
	 */
	Vector actualParamsDescs;

	/**
	 * The invoked task name.
	 */
	FQNDescription taskName;

	TaskInstructionDescription(int delayBefore, int line,
			NameSpaceDescription nsd,
			FQNDescription taskName,
			Vector actualParamsDescs) {
		super(delayBefore, line, nsd);
		this.actualParamsDescs = actualParamsDescs;
		this.taskName = taskName;
	}

	/**
	 * Creates the placeholders for the actuel parameters
	 * transfer and the DefaultInstruction for the task invocation.
	 */
	DefaultInstruction instantiate(NameSpace ns) throws ParseException {
		Vector actualParams = new Vector();
		Vector paramInstances;

		for(Enumeration e = actualParamsDescs.elements() ; e.hasMoreElements() ; ){
			//link the expressions to the caller's NameSpace (ns)
			try{
				actualParams.addElement(((ExpressionDescription)e.nextElement()).
						instantiate(ns));
			}catch(ParseException ex){
				xConsole.dumpStack(ex);
				throw new ParseException(super.toString() + " error:" + ex);
			}
		}

		NameSpace taskSpace;
		try{
			taskSpace = (NameSpace)ns.resolveName(taskName.instantiate(ns));
			//only checking that this name refers the correct NameSpace
			if(taskSpace == null)
				throw new ParseException(super.toString() +
						" error:symbol \"" + taskName +
				"\" not found");
			if(! (taskSpace.desc instanceof TaskDescription))
				throw new ClassCastException();
		}catch(ClassCastException ex){
			throw new ParseException(super.toString() + " error:" +
					taskName + " is not a task");
		}

		TaskDescription taskDescription = (TaskDescription) taskSpace.desc;
		try{
			paramInstances = taskDescription.createParams(taskSpace, actualParams);
		}catch(ParseException ex){
			xConsole.dumpStack(ex);
			throw new ParseException(super.toString() + " error:" + ex);
		}
		xConsole.debug("task description is: " + taskDescription);
		DefaultInstruction theJob;
		try{
			theJob = taskDescription.makeInstructionInstance(taskSpace);
		}catch(ParseException ex){
			xConsole.dumpStack(ex);
			xConsole.cout(ex.toString());
			throw new ParseException(super.toString() + "error inside enabled task");
		}
		return new TaskInstruction(delayBefore, ns, this, taskDescription,
				actualParams, paramInstances,
				theJob, next == null ? null :
					next.instantiate(ns));
	}

	public String toString(){
		String res =  super.toString() + taskName + "(" ;
		for(Enumeration e = actualParamsDescs.elements() ; e.hasMoreElements() ;){
			res += ((ExpressionDescription)e.nextElement()).toString();
			if(e.hasMoreElements())res += ", ";
		}
		res += ");";
		return res;
	}
}




